package com.jzo2o.health.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.common.model.CurrentUserInfo;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.health.enums.OrderPayStatusEnum;
import com.jzo2o.health.enums.OrderStatusEnum;
import com.jzo2o.health.mapper.OrdersCancelledMapper;
import com.jzo2o.health.model.OrderUpdateStatusDTO;
import com.jzo2o.health.model.UserThreadLocal;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.OrdersCancelled;
import com.jzo2o.health.model.dto.request.OrdersCancelReqDTO;
import com.jzo2o.health.service.IOrderCancelService;
import com.jzo2o.health.service.IOrderCommonService;
import com.jzo2o.health.service.IReservationSettingService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;

/**
 * 取消订单相关业务层实现
 * @author JIAN
 */
@Service
public class OrderCancelServiceImpl extends ServiceImpl<OrdersCancelledMapper, OrdersCancelled> implements IOrderCancelService {
    @Resource
    private IOrderCommonService orderCommonService;
    @Resource
    private IReservationSettingService reservationSettingService;

    @Override
    @Transactional
    public void cancelOrder(OrdersCancelReqDTO ordersCancelReqDTO) {
        CurrentUserInfo currentUser = UserThreadLocal.currentUser();
        if (ObjectUtils.isEmpty(currentUser) || ObjectUtils.isEmpty(currentUser.getId())) {
            throw new ForbiddenOperationException("无法获取用户信息无法取消");
        }

        Long orderId = ordersCancelReqDTO.getId();
        Orders orders = orderCommonService.getById(orderId);
        if (ObjectUtils.isEmpty(orders)) {
            throw new ForbiddenOperationException("订单不存在无法取消");
        }

        if (orders.getOrderStatus() != OrderStatusEnum.NO_PAY || orders.getPayStatus() != OrderPayStatusEnum.NO_PAY) {
            throw new ForbiddenOperationException("订单状态错误无法取消");
        }

        this.cancelOrder(OrdersCancelled.builder()
                .id(orderId)
                .cancelTime(LocalDateTime.now())
                .cancelReason(ordersCancelReqDTO.getCancelReason())
                .cancellerName(currentUser.getName())
                .cancellerId(currentUser.getId())
                .cancellerType(currentUser.getUserType())
                .build());

        // 已预约人数 - 1
        reservationSettingService.plusReservationCount(orders.getReservationDate(), -1);
    }

    @Override
    @Transactional
    public void cancelOrder(OrdersCancelled ordersCancelled) {
        Long orderId = ordersCancelled.getId();

        if (!orderCommonService.updateStatus(OrderUpdateStatusDTO.builder()
                .id(orderId)
                .originStatus(OrderStatusEnum.NO_PAY)
                .targetStatus(OrderStatusEnum.CANCELLED)
                .build())) {
            throw new DBException("更新订单表失败");
        }

        if (!SqlHelper.retBool(baseMapper.insert(ordersCancelled))) {
            throw new DBException("更新取消表失败");
        }
    }
}